package org.rmc.demo.service;

import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.security.*;
import org.rmc.demo.cfca.SignInfo;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.Calendar;

/**
 * @author ranmc
 * @date 2019-07-18
 */
@Service
public class ContractService {

    public void sign(String src, String out, SignInfo... infoArray){
        try {
            InputStream is = new FileInputStream(src);
            ByteArrayOutputStream os = null;
            for (SignInfo info : infoArray){
                // 读取PDF文件
                PdfReader reader = new PdfReader(is);
                // 创建输出流
                os = new ByteArrayOutputStream();
                //创建签章工具PdfStamper,最后一个boolean参数是否允许被追加签名
                PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0', null, true);
                // 获取数字签章属性对象
                PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
                // 备注
                appearance.setReason(info.getReason());
                // 位置
                appearance.setLocation(info.getLocation());
                if (info.getFacing()){
                    //设置签名的签名域名称,多次追加签名的时候,签名预名称不能一样,图片大小受表单域大小影响（过小导致压缩）
                    Rectangle r = new Rectangle(1, 1, 1, 1);
                    // 不指定名称会自动生成
                    appearance.setVisibleSignature(r, info.getPage(), info.getFieldName());
                } else {
                    //设置签名的签名域名称,多次追加签名的时候,签名预名称不能一样,图片大小受表单域大小影响（过小导致压缩）
                    Rectangle r = new Rectangle(info.getX1(), info.getY1(), info.getX2(), info.getY2());
                    // 不指定名称会自动生成
                    appearance.setVisibleSignature(r, info.getPage(), info.getFieldName());
                    //读取图章图片
                    if (info.getIsImage()){
                        Image image = Image.getInstance(info.getContent());
                        appearance.setSignatureGraphic(image);
                    } else {
                        BaseFont base = BaseFont.createFont("F:/Data/simsun.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                        Font font = new Font(base, 8, Font.BOLDITALIC);
                        appearance.setLayer2Font(font);
                        appearance.setLayer2Text(info.getContent());
                    }
                }
                // 是否批准签名
                appearance.setCertificationLevel(info.getSa());
                // 设置图章的显示方式，如下选择的是只显示图章（还有其他的模式，可以图章和签名描述一同显示）
                appearance.setRenderingMode(info.getRm());
                // 签署时间
                appearance.setSignDate(Calendar.getInstance());

                // 摘要算法
                ExternalDigest digest = new BouncyCastleDigest();
                // 签名算法
                ExternalSignature signature = new PrivateKeySignature(info.getPk(), info.getDa(), null);
                // 调用IText签名方法完成签章
                MakeSignature.signDetached(appearance, digest, signature, info.getChain(),
                        null, null, null, 0, info.getCs());
                //定义输入流为生成的输出流内容，以完成多次签章的过程
                is = new ByteArrayInputStream(os.toByteArray());
            }
            if (os != null){
                FileOutputStream outputStream = new FileOutputStream(out);
                outputStream.write(os.toByteArray());
                outputStream.flush();
                os.close();
            }
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
